package org.dromara.common.core.utils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

/**
 * 时间工具类
 *
 * @author ruoyi
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {

    public static final String YYYY = "yyyy";

    public static final String YYYY_MM = "yyyy-MM";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static final String[] PARSE_PATTERNS = {
        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }


    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getMonth() {
        return dateTimeNow(YYYY_MM);
    }



    /**
     * 得到n天之后的日期
     * @param days
     * @return
     */
    public static Date getBeginDayDate(Date date, int days) {
        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.setTime(date);
        if(days != 0){
            canlendar.add(Calendar.DAY_OF_MONTH, days); // 日期减 如果不够减会将月变动
        }
        canlendar.set(Calendar.HOUR_OF_DAY,0);
        canlendar.set(Calendar.MINUTE,0);
        canlendar.set(Calendar.SECOND,0);
        Date dateNow = canlendar.getTime();
        return dateNow;
    }

    public static String getDateBeginTime(Date date, int days) {
        return getTime(getBeginDayDate(date,days));
    }


    /**
     * 得到n天之后的日期
     * @param days
     * @return
     */
    public static Date getAfterDayDate(Date date, int days) {
        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.setTime(date);
        if(days!= 0){
            canlendar.add(Calendar.DAY_OF_MONTH, days); // 日期减 如果不够减会将月变动
        }
        canlendar.set(Calendar.HOUR_OF_DAY,23);
        canlendar.set(Calendar.MINUTE,59);
        canlendar.set(Calendar.SECOND,59);
        Date dateNow = canlendar.getTime();
        return dateNow;
    }


    public static String getDateEndTime(Date date, int days) {
        return getTime(getAfterDayDate(date,days));
    }



    ////////////////随机一个时间///////////////////
    /**
     * 随机一个时间
     * @param beginDate
     * @param endDate
     * @return
     */
    public static Date randomDate(Date beginDate,Date endDate ){
        if(beginDate.getTime() >= endDate.getTime()){
            return new Date();
        }
        long date = randomTime(beginDate.getTime(),endDate.getTime());
        return new Date(date);
    }
    public static long randomTime(long begin,long end){
        long rtn = begin + (long)(Math.random() * (end - begin));
        if(rtn == begin || rtn == end){
            return randomTime(begin,end);
        }
        return rtn;
    }

    public static List<Date> getRandomDateList(Date beginDate, Date endDate) throws ParseException{
        List<Date> resList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date temp = beginDate;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);//获得开始日期
        calendar.add(Calendar.DATE, 1);
        //上午 8点半到11点半
        String amStart = " 08:30:00";
        String amEnd = " 11:30:00";
        //下午 13点半点到17点半
        String pmStart = " 13:30:00";
        String pmEnd = " 17:30:00";

        while (temp.getTime() < endDate.getTime()){
            temp = calendar.getTime();
            String format = sdf.format(temp);
            calendar.add(Calendar.DAY_OF_MONTH,1);//天数+1

            //拼装生成上午的时间   yyyy-MM-dd HH:mm:ss
            String amStartFormat = format + amStart;// 上午开始时间
            Date amStartDate = sdf2.parse(amStartFormat);

            String amEndFormat = format + amEnd;// 上午结束时间
            Date amEndDate = sdf2.parse(amEndFormat);

            //上午开始~结束时间中，以10分钟为间隔  随机 获取一条时间
            Date amRandDate = getRandomDate(amStartDate,amEndDate);
            //添加到返回数组中
            resList.add(amRandDate);

            //生成下午的时间 yyyy-MM-dd HH:mm:ss
            String pmStartFormat = format + pmStart;// 下午开始时间
            Date pmStartDate = sdf2.parse(pmStartFormat);

            String pmEndFormat = format + pmEnd;// 下午结束时间
            Date pmEndDate = sdf2.parse(pmEndFormat);

            //下午开始~结束时间中，以10分钟为间隔  随机 获取一条时间
            Date pmRandDate = getRandomDate(pmStartDate, pmEndDate);

            //添加到返回数组中
            resList.add(pmRandDate);

        }

        return resList;
    }


    private static Date getRandomDate(Date beginTime, Date endTime){

        //随机抽取一个集合中的时间返回
        Random random = new Random();
        int randomTime = random.nextInt(10,50);//
        List<Date> randomList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginTime);//获得当前日期
        Date temp2 = beginTime;


        while (temp2.getTime() < endTime.getTime()){

            temp2 = calendar.getTime();
//            System.out.println("temp2:" + temp2);
            calendar.add(Calendar.MINUTE, randomTime);

            randomList.add(temp2);
        }

        List<Date> tempList = new ArrayList<>();
        for (Date date :randomList) {
            if(date.getTime() < endTime.getTime()){
                tempList.add(date);
            }
        }

        //随机抽取一个集合中的时间返回
//        Random random = new Random();
        int index = random.nextInt(tempList.size());
        return randomList.get(index);
    }

    ////////////////随机一个时间///////////////////


    public static String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }


    public static String getTime(Date date) {
        return dateTimeNow(date,YYYY_MM_DD_HH_MM_SS);
    }

    public static String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static String dateTimeNow(Date date, final String format) {
        return parseDateToStr(format, date);
    }
    public static String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), PARSE_PATTERNS);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }


    public static LocalDateTime dateToLocalDate(Date date){
        // 将 Date 转换为 Instant
        Instant instant = date.toInstant();
        // 将 Instant 转换为 LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
//        System.out.println("Date：" + date);
//        System.out.println("LocalDateTime：" + localDateTime);
        return localDateTime;
    }



    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 增加 LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor) {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 增加 LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor) {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }


    /**
     *  随机从日期集合里抽取限定数量的日期集合
     * @param days
     * @return
     */
    public static List<List<Date>> getRandomListByList(List<Date> days, int count){

        List<List<Date>> retDays = new ArrayList<>();

        Collections.shuffle(days); // 对列表进行打乱操作
        int size = days.size();
        int halfSize = count;

        List<Date> firstHalf = days.subList(0, halfSize); // 获取前半部分子列表
        List<Date> secondHalf = days.subList(halfSize, size); // 获取后半部分子列表

        Collections.sort(firstHalf);

        Collections.sort(secondHalf);
        System.out.println("第一个子列表：" + firstHalf);
        System.out.println("第二个子列表：" + secondHalf);
        retDays.add(firstHalf);
        retDays.add(secondHalf);
        return retDays;
    }


    public static List<Date> getDateListByCount(int count, int days){
        List<Date> tempList = new ArrayList<>();
        try {
            for (int i = 0; i < count;i++){
                List<Date> dateList = getRandomDateList(new Date(), DateUtils.addDays(new Date(),days));
                tempList.addAll(dateList);
            }
            Collections.sort(tempList);

            for (int i = 0; i < tempList.size(); i++){
                Date d0  =  tempList.get(i);
                if(i < tempList.size() - 1){
                    Date d1  =  tempList.get(i + 1);

                    LocalDateTime ld0 = dateToLocalDate(d0);
                    LocalDateTime ld1 = dateToLocalDate(d1);
//                    System.out.println("间隔分钟数： ld0 " + ld0.toString());
//                    System.out.println("间隔分钟数： ld1 " + ld1.toString());
                    int day0 = ld0.getDayOfMonth();
                    int day1 = ld1.getDayOfMonth();

                    int minuteD1 = ld1.getMinute();
                    int hourD1 = ld1.getHour();


                    Duration duration = Duration.between(ld0,ld1);
                    long minutes = duration.toMinutes();


                    d1 = resetTime(d1, day0,day1, hourD1,minuteD1,minutes);
                    tempList.set(i + 1,d1);
                }
            }

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        Collections.sort(tempList);
        return tempList;
    }

    private static Date resetTime(Date d1 ,int day0,int day1, int hourD1,int minuteD1, long minutes){
        if(minutes < 60){//间隔小于60分钟的 加上一个随机数
//            System.out.println(" 00000  day0 : " + day0 + "  day1 :" + day1 + " hourD1: " + hourD1 + " minuteD1 : " + minuteD1 + " minutes: " + minutes);
//            System.out.println("修正前： " + DateUtils.getTime(d1));
            Random random = new Random();
            int randomTime = random.nextInt(60,80);//
//                        System.out.println("随机数：" + randomTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d1);
            calendar.add(Calendar.MINUTE,randomTime - (int)minutes);
            d1 = calendar.getTime();
//            System.out.println("修正后的 1： " + DateUtils.getTime(d1));
//            tempList.set(i + 1,d1);

            LocalDateTime ld1 = dateToLocalDate(d1);
            day1 = ld1.getDayOfMonth();

            minuteD1 = ld1.getMinute();
            hourD1 = ld1.getHour();
        }
//        else if(day0 == day1 && hourD1 > 13 && minutes >= 200){ //超过200分钟的 减去100分钟
//            System.out.println("间隔超过200分钟, 共" + minutes + "分钟，往前调整100分钟");
//            System.out.println(" 1111111 day0 : " + day0 + "  day1 :" + day1 + " hourD1: " + hourD1 + " minuteD1 : " + minuteD1 + " minutes: " + minutes);
//            System.out.println("修正前： " + DateUtils.getTime(d1));
//            Calendar calendar = Calendar.getInstance();
//            calendar.setTime(d1);
//            calendar.add(Calendar.MINUTE,-100);
//            d1 = calendar.getTime();
//            System.out.println("修正后的 1： " + DateUtils.getTime(d1));
////            tempList.set(i + 1,d1);
//        }
        if(day0 == day1 && (hourD1 == 11 && minuteD1 > 30)){//11点半之后的
            System.out.println(" 222222   day0 : " + day0 + "  day1 :" + day1 + " hourD1: " + hourD1 + " minuteD1 : " + minuteD1 + " minutes: " + minutes);

            System.out.println("修正前： " + DateUtils.getTime(d1));

//                        System.out.println("随机数：" + randomTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d1);
            calendar.add(Calendar.HOUR_OF_DAY,2);
            d1 = calendar.getTime();
            System.out.println("修正后的 ： " + DateUtils.getTime(d1));
//            tempList.set(i + 1,d1);
        } else if(day0 == day1 && (hourD1 == 12)){
            System.out.println(" 33333  day0 : " + day0 + "  day1 :" + day1 + " hourD1: " + hourD1 + " minuteD1 : " + minuteD1 + " minutes: " + minutes);

            System.out.println("修正前： " + DateUtils.getTime(d1));
            Random random = new Random();
            int randomTime = random.nextInt(70,100);//
//                        System.out.println("随机数：" + randomTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d1);
            calendar.add(Calendar.MINUTE,randomTime);
            d1 = calendar.getTime();
            System.out.println("修正后的 1： " + DateUtils.getTime(d1));
//            tempList.set(i + 1,d1);
        } else if(day0 == day1 && (hourD1 == 13 && minuteD1 < 30)){
            System.out.println(" 4444444 day0 : " + day0 + "  day1 :" + day1 + " hourD1: " + hourD1 + " minuteD1 : " + minuteD1 + " minutes: " + minutes);

            System.out.println("修正前： " + DateUtils.getTime(d1));
            Random random = new Random();
            int randomTime = random.nextInt(20,40);//
//                        System.out.println("随机数：" + randomTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d1);
            calendar.add(Calendar.MINUTE,randomTime);
            d1 = calendar.getTime();
            System.out.println("修正后的 1： " + DateUtils.getTime(d1));
//            tempList.set(i + 1,d1);
        }
        return d1;
    }


    public static void main(String[] args) {
//        Date d = randomDate(new Date(), DateUtils.addDays(new Date(),5));

//        try {
//            List<Date> tempList = new ArrayList<>();
//            for (int i = 0;i < 3;i++){
//                List<Date> dateList = getRandomDateList(new Date(), DateUtils.addDays(new Date(),5));
//                tempList.addAll(dateList);
//            }
//            Collections.sort(tempList);
//
//            for (int i = 0; i < tempList.size() / 2; i++){
//                Date d0  =  tempList.get(i * 2);
//                System.out.println("时间 0： " + DateUtils.getTime(d0));
//                if(i < tempList.size() - 1){
//                    Date d1  =  tempList.get(i * 2+ 1);
////                    System.out.println("时间 1： " + DateUtils.getTime(d1));
//
//                    LocalDateTime ld0 = dateToLocalDate(d0);
//                    LocalDateTime ld1 = dateToLocalDate(d1);
////                    System.out.println("间隔分钟数： ld0 " + ld0.toString());
////                    System.out.println("间隔分钟数： ld1 " + ld1.toString());
//
//                    Duration duration = Duration.between(ld0,ld1);
//                    long minutes = duration.toMinutes();
//                    if(minutes < 60){
//                        Calendar calendar = Calendar.getInstance();
//                        calendar.setTime(d1);
//                        calendar.add(Calendar.MINUTE,70 - (int)minutes);
//                        d1 = calendar.getTime();
////                        System.out.println("修正后的 1： " + DateUtils.getTime(d1));
//                        tempList.set(i* 2 + 1,d1);
//                    }
//
////                    System.out.println("间隔分钟数： " + minutes);
//                }
//            }
//
//            Collections.sort(tempList);
//            for (Date d : tempList){
//                System.out.println(DateUtils.getTime(d));
//            }
//
//        } catch (ParseException e) {
//            throw new RuntimeException(e);
//        }

        List<Date> days = getDateListByCount(1,5);
        for (Date d : days){
            System.out.println(DateUtils.getTime(d));
        }


    }
}
